(function($){
    $.maZoom = function(el, options){
        // To avoid scope issues, use 'base' instead of 'this'
        // to reference this class from internal events and functions.
        var base = this;

        // Access to jQuery and DOM versions of element
        base.$el = $(el);
        base.el = el;
        base.small = $(el).find('.small');
        base.zoom = $(el).find('.zoom');
        base.imgContent = $(el).find('.small,.zoom');
        base.smallImg = $(el).find('.small img');
        base.zoomImg = $(el).find('.zoom img');
        base.x = 0;
        base.y = 0;

        // Add a reverse reference to the DOM object
        base.$el.data("maZoom", base);

        base.init = function(){
            base.options = (options === undefined) ? $.maZoom.defaultOptions : options ;
            base.imgContent.each(function(){
                $(this).click(base.clickImage);
            });
        };

        base.clickImage = function(e) {
            var className = $(this).attr('class').split(' ')[0];
            switch(className) {
                case 'small':
                    base.transition(e);
                break;
                case 'zoom':
                    base.zoom.unbind('mousemove').fadeOut('slow').hide();
                    base.small.fadeIn('slow');
                break;
            }
        };

        base.restoreDefaults = function() {
            base.zoomImg.removeAttr('style');
            base.smallImg.removeAttr('style');
            base.zoom.removeAttr('style');
            base.small.removeAttr('style');
            base.zoom.hide();
            base.small.show();
        }

        base.transition = function(cur) {
            base.restoreDefaults();

            var mousePosX = cur.pageX - base.small.offset().left;
            var mousePosY = cur.pageY - base.small.offset().top;
            
            var smallWidth = base.smallImg.width();
            var smallHeight = base.smallImg.height();

            var bigWidth = base.options.zoomImageWidth;
            var bigHeight = base.options.zoomImageHeight;

            var ratio = bigWidth/smallWidth;
            var newX = mousePosX-(mousePosX*ratio);
            var newY = mousePosY-(mousePosY*ratio);

            base.zoomImg.width(smallWidth);
            base.small.fadeOut(250,function(){
                base.zoom.fadeIn(250,function(){
                    base.zoomImg.animate({
                        width: bigWidth,
                        height: bigHeight,
                        marginTop: newY,
                        marginLeft: newX
                    },250,'linear',function(){
                        base.zoom.bind('mousemove',base.mouseMoveFunc);
                    });
                });
            });
        };

        base.mouseMoveFunc = function(cur) {
            var offsetX = base.zoomImg.width()-base.zoom.width();
            var offsetY = base.zoomImg.height()-base.zoom.height();

            var mousePosX = cur.pageX - base.zoom.offset().left;
            var mousePosY = cur.pageY - base.zoom.offset().top;

            var percentX = mousePosX/base.zoom.width();
            var percentY = mousePosY/base.zoom.height()

            percentX = (percentX>1)?1:percentX;
            percentX = (percentX<0)?0:percentX;
            percentY = (percentX>1)?1:percentY;
            percentY = (percentY<0)?0:percentY;

            var posImgX = base.zoomImg.position().left;
            var posImgY = base.zoomImg.position().top;

            base.x = -((posImgX+(offsetX*percentX)));
            base.y = -((posImgY+(offsetY*percentY)));

            base.goTo();
        };

        base.goTo = function() {
            base.zoomImg.stop().animate({
                marginLeft: base.x,
                marginTop:  base.y
            },1000,'easeOutCubic');
        }

        base.init();
    };

    $.maZoom.defaultOptions = {
        zoomImageWidth: 2000,
        zoomImageHeight: 1123
    };

    $.fn.maZoom = function(options){
        return this.each(function(){
            (new $.maZoom(this, options));
        });
    };

})(jQuery);